package com.ophiux.wechat.executor;

import java.util.SortedMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ophiux.wechat.model.CM_UnifiedOrderRequest;
import com.ophiux.wechat.model.UnifiedOrderResponse;
import com.ophiux.wechat.utils.CommonUtil;
import com.ophiux.wechat.utils.MapBuilder;
import com.ophiux.wechat.utils.StringUtil;
import com.ophiux.wechat.utils.WeChatSignUtil;
import com.ophiux.wechat.utils.XmlUtil;


/**
 * 微信普通商户统一下单执行器
 * @author chenh
 *2016-11-17
 */
public class UnifiedOrderExecutor implements Executor<UnifiedOrderResponse>{

 	private static Logger logger = LoggerFactory.getLogger(UnifiedOrderExecutor.class);
	
	/**
	 * 返回状态标识
	 */
	private String RETURN_SUCCESS = "SUCCESS";
	private String RETURN_FAIL = "FAIL";
	/**
	 * 业务结果处理结果标识
	 */
	private String RESULT_SUCCESS = "SUCCESS";
	private String RESULT_FAIL = "FAIL";
	
	/**
	 * 签名算法失败错误
	 */
	private String SIGN_BUILD_ERROR = "600";
	private String SIGN_BUILD_ERROR_MSG = "签名算法失败错误";
	
	/**
	 * 微信公众号支付-普通商户-统一下单URL地址
	 */
	private static String ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
	
	/**
	 * 微信公众号支付-普通商户-统一下单请求实体
	 */
	private  CM_UnifiedOrderRequest cm_unifiedorder_request;
	
	/**
	 * 商户平台api安全秘钥
	 */
	private String api_key;
	
	 
	public UnifiedOrderExecutor(CM_UnifiedOrderRequest _cm_unifiedorder_request,
			String _api_key ){
		this.cm_unifiedorder_request = _cm_unifiedorder_request;
		this.api_key = _api_key;
	}
	
	
	@Override
	public UnifiedOrderResponse execute() {
		// TODO Auto-generated method stub
		logger.info("统一下单，原始提供参数："+cm_unifiedorder_request.toString());
		UnifiedOrderResponse uifiedOrderResp = new UnifiedOrderResponse();
		/**
		 * 获取非空参数
		 */
		
		String appid = cm_unifiedorder_request.getAppid();
		String mch_id = cm_unifiedorder_request.getMch_id();
		String nonce_str = CommonUtil.getNonceStr();
		String body = cm_unifiedorder_request.getBody();
		String attach = cm_unifiedorder_request.getAttach();
		String out_trade_no = cm_unifiedorder_request.getOut_trade_no();
		String total_fee = cm_unifiedorder_request.getTotal_fee();
		String spbill_create_ip = cm_unifiedorder_request.getSpbill_create_ip();
		String notify_url = cm_unifiedorder_request.getNotify_url();
		String trade_type = cm_unifiedorder_request.getTrade_type();
		String openid = cm_unifiedorder_request.getOpenid();
		
		String api_key = this.api_key;
		
		/**
		 * 生成SortMap
		 */
		String [] keys = {"appid","mch_id","nonce_str","body","out_trade_no",
				"total_fee","spbill_create_ip","notify_url","trade_type","openid"};
		String []values = {appid,mch_id,nonce_str,body,out_trade_no,
				total_fee,spbill_create_ip,notify_url,trade_type,openid};
		
		SortedMap<String, String> packageParams = MapBuilder.getInstance()
									.buildSortMap(keys, values);
		
		if(packageParams == null){
			logger.info("签名创建失败:"+keys+values);
			uifiedOrderResp.setError_code(SIGN_BUILD_ERROR);
			uifiedOrderResp.setError_msg(SIGN_BUILD_ERROR_MSG);
			return uifiedOrderResp;
		}
		/**
		 * 生成签名
		 */
		String sign = WeChatSignUtil.getInstance(api_key).createSign(packageParams);
		
		String order_xmlParam = "<xml>" +
				"<appid>" +appid+
				"</appid>" + "<mch_id>"
				+ mch_id + "</mch_id>"
			    + "<nonce_str>" + nonce_str
				+ "</nonce_str>" + "<sign>" + sign + "</sign>"
				+ "<body><![CDATA[" + body + "]]></body>" 
				+ "<out_trade_no>" + out_trade_no
				+ "</out_trade_no>" + "<attach>" + attach + "</attach>"
				+ "<total_fee>" + total_fee + "</total_fee>"
				+ "<spbill_create_ip>" + spbill_create_ip
				+ "</spbill_create_ip>" + "<notify_url>" + notify_url
				+ "</notify_url>" + "<trade_type>" + trade_type
				+ "</trade_type>" + "<openid>" + openid + "</openid>"
				+ "</xml>";
	 
		
		logger.info("HTTPS调用统一下单接口,传入参数："+order_xmlParam);
		/**
		 * HTTPS请求统一下单
		 */
		String order_response = "";
		try {
			 order_response = CommonUtil.httpsRequest(ORDER_URL, 
					CommonUtil.HTTP_POST, order_xmlParam);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			uifiedOrderResp.setError_code(HTTPS_ERROR);
			uifiedOrderResp.setError_msg(HTTPS_ERROR_MSG);
			logger.info("HTTPS调用统一下单接口异常错误,传入参数："+order_xmlParam);
			return uifiedOrderResp;
		}
		logger.info("HTTPS调用统一下单接口,返回结果："+order_response);
		/**
		 * 分析统一下单结果
		 */
		uifiedOrderResp = analysisUnifiedOrderResult(order_response);
		return uifiedOrderResp;
		
	}
	
	/**
	 * 统一下单成功
	 */
	private String ERROR_SUCCESS = "200";
	private String ERROR_SUCCESS_MSG = "统一下单成功";
	/**
	 * 通信错误，即return_code = FAIL
	 */
	private String CONNECT_ERROR = "500";
	private String CONNECT_ERROR_MSG = "通信错误";
	
	/**
	 * 解析异常
	 */
	private String ANALYSIS_ERROR = "501";
	private String ANALYSIS_ERROR_MSG = "结果解析异常";
	
	/**
	 * 下单接口HTTPS请求错误
	 */
	private static String HTTPS_ERROR_MSG = "HTPS方式调用--统一下单操作异常";
	private static String HTTPS_ERROR = "404";
	
	/**
	 * 解析统一下单返回结果
	 * @param response   返回数据
	 */
	public UnifiedOrderResponse analysisUnifiedOrderResult(String response){
		
		UnifiedOrderResponse uifiedOrderResp = new UnifiedOrderResponse();
		if(StringUtil.isEmpty(response)){
			/**
			 * 响应结果为空
			 */
			uifiedOrderResp.setError_code(HTTPS_ERROR);
			uifiedOrderResp.setError_msg(HTTPS_ERROR_MSG);
			return uifiedOrderResp;
		}
		try {
			
			
			XmlUtil xm=new XmlUtil();
			/**
			 * SUCCESS/FAIL
				此字段是通信标识，非交易标识，交易是否成功需要查看result_code来判断
			 */
			String return_code = "";
			/**
			 * 返回信息，如非空，为错误原因
				签名失败
				参数格式校验错误
			 */
			String return_msg;
			
			String result_code = "";
			
			return_code=xm.getValue(response, "return_code");
			if(return_code.equals(RETURN_SUCCESS)){
				/**
				 * 接口调用成功
				 */
				//获取业务结果
				result_code = xm.getValue(response, "result_code");
				if(result_code.equals(RESULT_SUCCESS)){
					/**
					 * 统一下单成功
					 */
					String trade_type = xm.getValue(response, "trade_type");
					String prepay_id = xm.getValue(response, "prepay_id");
					
					String code_url = "";
					if(trade_type.equals("NATIVE")){
					   code_url = xm.getValue(response, "code_url");
					}
					
					uifiedOrderResp.setError_code(ERROR_SUCCESS);
					uifiedOrderResp.setError_msg(ERROR_SUCCESS_MSG);
					uifiedOrderResp.setTrade_type(trade_type);
					uifiedOrderResp.setPrepay_id(prepay_id);
					uifiedOrderResp.setCode_url(code_url);
					
				}else{
					/**
					 * 统一下单失败
					 * 详情请参照微信支付开发文档的错误码
					 */
					String err_code = xm.getValue(response, "err_code");
					String err_code_des = xm.getValue(response, "err_code_des");
					uifiedOrderResp.setError_code(err_code);
					uifiedOrderResp.setError_msg(err_code_des);
				}
				
			}else{
				/**
				 * 接口调用失败
				 */
				return_msg = xm.getValue(response, "return_msg");
				uifiedOrderResp.setError_code(CONNECT_ERROR);
				uifiedOrderResp.setError_msg(return_msg);
				
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			uifiedOrderResp.setError_code(ANALYSIS_ERROR);
			uifiedOrderResp.setError_msg(ANALYSIS_ERROR_MSG);
			logger.info("统一下单返回结果解析异常，返回结果："+response);
		}
		
		return uifiedOrderResp;
		
	}
	

}
